﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using MyRegister;
using System.Configuration;
using IniRw;
namespace APRIL
{
    public partial class MainForm : Form
    {
        private StreamReader _rstream = null;
        private StreamWriter _wstream = null;

        /// <summary>
        /// 串行通信线程
        /// </summary>
        private System.Threading.Thread SerialCommThread = null;

        /// <summary>
        /// 写使能
        /// </summary>
        private byte[] EWEN = new byte[6] { 0x55, 0x53, 0x42, 0x49, 0x04, 0xC5 };
        /// <summary>
        /// 擦除整片
        /// </summary>
        private byte[] ERAL = new byte[6] { 0x55, 0x53, 0x42, 0x49, 0x04, 0x85 };

        /// <summary>
        /// 写命令
        /// </summary>
        private byte[] WRITE = new byte[8] { 0x55, 0x53, 0x42, 0x49, 0x05, 0x00, 0xA5, 0x5A };

        /// <summary>
        /// 写禁止
        /// </summary>
        private byte[] EWDS = new byte[6] { 0x55, 0x53, 0x42, 0x49, 0x04, 0x05 };

        private List<String> dataList = null;

        private List<byte[]> dataApr = null;

        Dictionary<string, string> APRMap = new Dictionary<string, string>();

        /// <summary>
        /// 每两条指令之间的时间间隔(单位：毫秒)
        /// </summary>
        private int Interval = 25;

        private string IniPath = Application.StartupPath + @"\" + "APRILCfg.ini";

        public MainForm()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
            this.DoubleBuffered = true;
           
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                if (File.Exists(IniPath) == false)
                {
                    StreamWriter file = new StreamWriter(IniPath, true);

                    file.WriteLine("[Config]\r");

                    file.WriteLine("Port=COM1");
                    file.WriteLine("BaudRate=9600");
                    file.WriteLine(string.Format("Interval={0}", Interval));
                    file.Close();
                }
                else
                {
                    SerialPort.PortName = ZT_INI.GetINI("Config", "Port", "", IniPath);
                    SerialPort.BaudRate = Int32.Parse(ZT_INI.GetINI("Config", "BaudRate", "", IniPath));
                    Interval = Int32.Parse(ZT_INI.GetINI("Config", "Interval", "", IniPath));
                }
            }
            catch
            {
                if (File.Exists(IniPath))
                    File.Delete(IniPath);
                StreamWriter file = new StreamWriter(IniPath, true);
                file.WriteLine("[Config]\r");
                file.WriteLine(string.Format("Port={0}", SerialPort.PortName));
                file.WriteLine(string.Format("BaudRate={0}", SerialPort.BaudRate));
                file.WriteLine(string.Format("Interval={0}", Interval));
                file.Close();

                SerialPort.PortName = ZT_INI.GetINI("Config", "Port", "", IniPath);
                SerialPort.BaudRate = Int32.Parse(ZT_INI.GetINI("Config", "BaudRate", "", IniPath));
                Interval = Int32.Parse(ZT_INI.GetINI("Config", "Interval", "", IniPath));
            }
            OpenSerialPort();
            AddStatus("------------------------------------------------");
            AddStatus("APR Info Loader");
            AddStatus("Version 1.0");
            AddStatus("Copyright @ Sdyx Co.,Ltd .Beijing.China");
            AddStatus(string.Format("Session started {0} at {1}", DateTime.Now.ToString("MM/dd/yyyy "), DateTime.Now.ToString("HH:mm")));
            AddStatus("------------------------------------------------");
            //////////////////////////////////////////////////////////////////////////
            pBar.Visible = false;
            btnProgram.Visible = false;
        }
        private void CommandPrase(string strRev)
        {
            // this.lsbShowInfo.Items.Add(strRev);
            switch (strRev)
            {
                case "#84@00B8A5\r":
                    break;
                default:
                    this.lsbShowInfo.Items.Add(strRev);
                    break;
            }
        }

        private void SerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
          //  string strRev = SerialPort.ReadLine();
          //  CommandPrase(strRev);
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            try
            {/*
                if (SerialPort.IsOpen)
                {
                    byte[] data = StringToByteArray(txtCommand.Text);
                    SerialPort.Write(data, 0, data.Length);
                }*/
                test(APRMap[string.Format("{0}-{1}", cboMapID.SelectedItem.ToString(), cboAPRID.SelectedItem.ToString())]);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
            finally
            { 
            
            }
           
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                if (SerialPort.IsOpen)
                {
                  
                }
            }
            catch
            {

            }
            finally
            {

            }
        }

        private void btnSaveLog_Click(object sender, EventArgs e)
        {
            saveFileDialog.FileName=DateTime.Now.ToString("yyyy-MM-dd")+".log";
            saveFileDialog.RestoreDirectory = true;

            saveFileDialog.Filter = "APR Information Loader Log(*.log,*.txt)|*.log;*.txt";
            saveFileDialog.ShowDialog();
          
        }

        private void btnQuit_Click(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void saveFileDialog_FileOk(object sender, CancelEventArgs e)
        {
   
            WriteLstToTxt(lsbShowInfo, saveFileDialog.FileName);
           
        }

        private void WriteLstToTxt(ListBox lst, string spath) //listbox 写入txt文件
        {
            int count = lst.Items.Count;
            _wstream = new StreamWriter(spath);
            for (int i = 0; i < count; i++)
            {
                string data = lst.Items[i].ToString();
                _wstream.Write(data);
                _wstream.WriteLine();
            }
            _wstream.Flush();
            _wstream.Close();
        }


        private void ReadTxtToLst(ListBox lst, string spath) //listbox 读取txt文件
        {
            _rstream = new StreamReader(spath, System.Text.Encoding.Default);
            string line;
            while ((line = _rstream.ReadLine()) != null)
            {
                lst.Items.Add(line);
            }
            _rstream.Close();
        }

        private bool OpenSerialPort()
        {
            bool abool = false;
            SerialPort.Open();
            if (SerialPort.IsOpen)
            {
                this.Text = "APRIL----" + "已连接 " + SerialPort.PortName;
               // btnTest.Visible = true;
               // txtCommand.Visible = true;

            }
            else
            {
                this.Text = "APRIL----" + "未连接 ";
                btnTest.Visible = false;
                txtCommand.Visible = false;

            }
            return abool;
        }
        
        private void btnSettings_Click(object sender, EventArgs e)
        {
            try
            {
                this.Text = "APRIL";
                if (SerialPort.IsOpen)
                    SerialPort.Close();
                SetSerialPortForm sspf = new SetSerialPortForm(SerialPort);
                if (sspf.ShowDialog() == DialogResult.OK)
                {
                    SerialPort = sspf.serialPort; 
                    if (File.Exists(IniPath))
                    File.Delete(IniPath);
                    StreamWriter file = new StreamWriter(IniPath, true);
                    file.WriteLine("[Config]\r");
                    file.WriteLine(string.Format("Port={0}", SerialPort.PortName));
                    file.WriteLine(string.Format("BaudRate={0}", SerialPort.BaudRate));
                    file.WriteLine(string.Format("Interval={0}", Interval));
                    file.Close();
                }
                SerialPort.PortName = ZT_INI.GetINI("Config", "Port", "", IniPath);
                SerialPort.BaudRate = Int32.Parse(ZT_INI.GetINI("Config", "BaudRate", "", IniPath));
                Interval = Int32.Parse(ZT_INI.GetINI("Config", "Interval", "", IniPath));
    
                OpenSerialPort();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "所有APR报文文件(txt,HEX,hex,apr)|*.txt;*.HEX;*.hex;*.apr|所有文件 (*.*)|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    txtPath.Text = ofd.FileName;
                    dataList = ReaHexFile(ofd.FileName);
                    foreach (string str in dataList)
                    {
                        Analytical at = new Analytical();
                        if (at.Prase(str) == 0)
                        {
                            APRMap.Add(at.id, at.tag);
                            cboMapID.Items.Add(at.map);
                            cboAPRID.Items.Add(at.apr);
                        }
                    }  
                    //  btnProgram.Enabled = false;
                    btnProgram.Visible = true;
                    pBar.Visible = true;
                    lblMapID.Visible = true;
                    lblAPRID.Visible = true;
                    //  txtMapID.Visible = true;
                    //  txtAPRID.Visible = true;
                    cboAPRID.Visible = true;
                    cboMapID.Visible = true;
                    cboMapID.SelectedIndex = 0;
                    cboAPRID.SelectedIndex = 0;
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message, "文件错误");
                }
            }
           
        }

        private byte[] StringToByteArray(string telestring)
        {
            byte[] tx_buf = new byte[] { };
            telestring = telestring.Replace(" ", "");
            if ((telestring.Length % 2) != 0)
                telestring += " ";

            int strlen = telestring.Length;
            tx_buf = new byte[strlen / 2];
            for (int i = 0; i < strlen / 2; i++)
            {
                string sss = telestring.Substring(i * 2, 2);
                tx_buf[i] = Convert.ToByte(sss, 16);
                //tx_buf[i] = Byte.Parse(sss, System.Globalization.NumberStyles.HexNumber);

            }
            return tx_buf;
        }

        private byte[] stringArrayToByteArray(List<String> sList)
        {
            byte[] data = new byte[] { };
            try
            {

                if (sList != null)
                {
                    int count = sList.Count;
                    List<byte> ByteArrayList = new List<byte>();
                    foreach (string str in sList)
                    {
                        byte[] ByteArray = StringToByteArray(str);
                        foreach (byte b in ByteArray)
                        {
                            ByteArrayList.Add(b);
                        }
                    }
                    data = ByteArrayList.ToArray();
                }
                else
                {
                    data = null;
                }
            }
            catch
            {
                data = null;
            }

            return data;
        }

        private List<String> ReaHexFile(string path)
        {
            StreamReader sr = new StreamReader(path);
            List<String> sList = new List<String>();
            string nextLine;
            while ((nextLine = sr.ReadLine()) != null)
            {
                if (nextLine == "")
                {
                    // break;
                }
                nextLine = nextLine.Trim();
                sList.Add(nextLine);
            }
            return sList;
        }

        private void ProgramProcess()
        {
            try
            {
                AddStatus("------------------------------------------------");
                if (SerialPort.IsOpen)
                {
                    // 写使能
                    SerialPort.Write(EWEN, 0, 6);
                    System.Threading.Thread.Sleep(Interval);
                    AddStatus(string.Format(DateTime.Now.ToString("HH:mm:ss") + "> EWEN Command Completed"));
                    // 擦除整片
                    SerialPort.Write(ERAL, 0, 6);
                    System.Threading.Thread.Sleep(Interval);
                    AddStatus(string.Format(DateTime.Now.ToString("HH:mm:ss") + "> ERAL Command Completed"));
                    // pBar.Visible = true;
                    pBar.Maximum = 255;
                    /// <summary>
                    /// 写命令
                    /// </summary>
                    if (dataList != null)
                    {
                        byte[] allData = Encode(APRMap[string.Format("{0}-{1}", cboMapID.SelectedItem.ToString(), cboAPRID.SelectedItem.ToString())]);//stringArrayToByteArray(dataList);

                        int dCount = allData.Length;
                        if (dCount > 512)
                        {
                            dCount = 512;
                        }
                        dCount /= 2;
                        pBar.Maximum = dCount - 1;
                        for (int i = 0; i < dCount; i++)
                        {
                            WRITE[5] = (byte)i;
                            WRITE[7] = allData[2 * i];
                            WRITE[6] = allData[2 * i + 1];
                            SerialPort.Write(WRITE, 0, 8);
                            pBar.Value = i;
                            AddStatus(string.Format("WRITE MEMORY [{0:X02}]:{1:X02} {2:X02}", i, WRITE[6], WRITE[7]));
                            System.Threading.Thread.Sleep(Interval);
                        }
                        System.Threading.Thread.Sleep(Interval);
                    }
                    AddStatus(string.Format(DateTime.Now.ToString("HH:mm:ss") + "> WRITE Command Completed"));
                    // 写禁止
                    SerialPort.Write(EWDS, 0, 6);
                    System.Threading.Thread.Sleep(Interval);
                    AddStatus(string.Format(DateTime.Now.ToString("HH:mm:ss") + "> EWDS Command Completed"));
                    AddStatus(string.Format(DateTime.Now.ToString("HH:mm:ss") + "> Command Completed"));
                    MessageBox.Show(string.Format("Command Completed"));
                }
                else
                {
                    this.lsbShowInfo.Items.Add(string.Format(DateTime.Now.ToString("HH:mm:ss") + "> Serial Error!"));
                    MessageBox.Show(string.Format("Serial Error!"));
                }

                this.lsbShowInfo.Items.Add("------------------------------------------------");
            }
            catch
            {

            }
            finally
            {
                this.btnTest.Enabled = true;
                this.txtCommand.Enabled = true;
            }
        }

        private void btnProgram_Click(object sender, EventArgs e)
        {
            try
            {
                this.btnTest.Enabled = false;
                this.txtCommand.Enabled = false;
                if (SerialCommThread != null)
                {
                    SerialCommThread.Abort();
                }
                SerialCommThread = new System.Threading.Thread(new System.Threading.ThreadStart(ProgramProcess));
                SerialCommThread.Start();
            }
            catch
            {
                this.btnTest.Enabled = true;
                this.txtCommand.Enabled = true;
                return;
            }
          
        }

        private delegate void AddStatusDelegate(string message);
        /// <summary>
        /// 输出状态信息
        /// </summary>
        /// <param name="message"></param>
        public void AddStatus(string message)
        {
            if (lsbShowInfo.InvokeRequired)
            {
                AddStatusDelegate status = new AddStatusDelegate(AddStatus);
                lsbShowInfo.Invoke(status, new object[] { /*DateTime.Now.ToString() + " " + */message });
            }
            else
            {
                this.lsbShowInfo.Items.Add(message);
            }
        }

        private void MainForm_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.O:
                    btnOpen_Click(sender, e);
                    break;
                case Keys.S:
                    btnSaveLog_Click(sender, e);
                    break;
                case Keys.T:
                    btnSettings_Click(sender, e);
                    break;
                case Keys.P:
                    btnProgram_Click(sender, e);
                    break;
                case Keys.Q:
                case Keys.Escape:
                    btnQuit_Click(sender, e);
                    break;
                default:
                    break;
            }
        }

        private byte[] Encode(string s = "b")
        {
            byte[] buffer = new byte[] { };
            AprEncode ae = new AprEncode(s);
            buffer = ae.Encode();
          
            return buffer;
        }

        private void test(string s = "b")
        {
            
            byte[] buffer = new byte[] { };

            buffer = Encode(s);
            string s1 = "";
            for (int i = 0; i < buffer.Length; i++)
            {
                s1 += buffer[i].ToString("X02") + " ";
            }
            AddStatus(s1);

        }
        

    }
}
